#pragma once

#include "Common.hpp"

const int line_size = 1024;

class Command
{
public:
    Command()
    {
        _white_list.insert("ls");
        _white_list.insert("pwd");
        _white_list.insert("ls -l");
        _white_list.insert("touch");
        _white_list.insert("ll");
        _white_list.insert("whoami");
        _white_list.insert("who");
    }

    bool SafeCheck(const string& cmdstr)
    {
        return _white_list.find(cmdstr) != _white_list.end();
    }

    string Execute(string cmdstr)
    {
        // 给你一个命令cmdstr(比如"ls -l")，让你执行，执行完后返回
        // 正常流程：1.pipe 2.fork() 3.dup2() 4.exec*函数
        // 这里可以用一个popen函数，可以帮你执行上面的操作（除了重定向dup2）
        if(!SafeCheck(cmdstr))
        {
            return string(cmdstr + ": command denied");
        }
        FILE* fp = popen(cmdstr.c_str(), "r");
        if(fp == nullptr)
        {
            return string("Failed！");
        }
        char buffer[line_size];
        string result;
        while(true)
        {
            char* ret = ::fgets(buffer, line_size, fp);
            if(ret == nullptr)
            {
                break;
            }
            result += ret;
        }
        return result.empty() ? string("Done") : result;
    }
    
    ~Command(){}
private:
    set<string> _white_list;  // 一个白名单，表示能够执行的所有命令
};